1. /*
  2. By making sine and cosine table
  3. inline fftType fftSinR(int n, int d){ return fftSin(n*(M_PI_4/d)); }
  4. inline fftType fftCosR(int n, int d){ return fftCos(n*(M_PI_4/d)); }
  5. to evaluate
  6. sin((pi/4 )*(j/w)) or cos((pi/4 )*(j/w)) (w = 2^k, j/w <= 8).
  7. Used in "void rdft(int n, int isgn, fftType *a, int *ip, fftType *w);" only.
  8. Both j and w integers. The maximum value of w = fftMaxArraySize
  9. in "sfft.h)
  10. const uint fftMaxArraySize = 1u << FFT_MAX_SIZE_BITS;
  11. */
  12. #include "sn.h"
  13. long double ldpow10(const int n);
  14. long double doubleLD(const SDouble& sd, int err);
  15. static fftType *sine = NULL; //table of sine
  16. static fftType *cosine = NULL; //table of cosine
  17. static int L; // FFT_MAX_SIZE_BITS;
  18. static long Nmax; // fftMaxArraySize; Nmax = 1 << L
  19. static long Nmax2; // Nmax/2
  20. static long Nmax4; // Nmax/4
  21. static long Nmax3_4; // 3*Nmax/4
  22. static long Nmax8; // Nmax/8
  23. static long tableSize = 0;
  24. static void SetNSize(int maxsizebit){
  25. L = maxsizebit;
  26. Nmax = 1 << L; Nmax2 = Nmax/2; Nmax4 = Nmax/4; Nmax3_4 = 3*Nmax4; Nmax8 = Nmax/8;
  27. tableSize =Nmax4 +1;
  28. }
  29. long FFTSineTableSize(){
  30. return tableSize;
  31. }
  32. long FFTSineTableUsedMemory(){
  33. return tableSize*sizeof(fftType);
  34. }
  35. /*--------------------------------------------------
  36. Here we have the table of sine[k] = sin(2*k*pi/N) where N = 2^L .
  37. We want sin (pi/4)*(j/w) from the table sine[k] (0<= k <= N/4).
  38. Map (pi/4)*(j/w) = 2*k*pi/N, k = ((N/8)*j)/w
  39. (pi/4)*(j/w) = (pi/2)*(j/(2*w))=(pi/2)*n (n = j/(2*w))
  40. ----------------------------------------------------*/
  41. static void ErrorEnd(){
  42. cerr << "out of range in sine table." << endl;
  43. exit(-1);
  44. }
  45. fftType fftSinR(long j, long w){
  46. if(!j) return 0.0;
  47. long k =(Nmax8/w)*j; // (Nmax8*j)/w; pay attention to over flow
  48. if(j>8*w || k > Nmax || k <0) ErrorEnd();
  49. if(k <= Nmax4) return sine[k]; // k<N/4
  50. if(k <= Nmax2) return sine[Nmax2-k];// N/4<k<N/2
  51. if(k <= Nmax3_4) return -sine[k-Nmax2]; // N/2<k<(3/4)N
  52. return -sine[Nmax-k]; // (3/4)N<k<N
  53. }
  54. fftType fftCosR(long j, long w){
  55. if(!j) return 1.0;
  56. long k = (Nmax8/w)*j; //(Nmax8*j)/w;
  57. if(j>8*w || k > Nmax || k < 0) ErrorEnd();
  58. if(k <= Nmax4) return sine[Nmax4-k];// k<N/4
  59. if(k <= Nmax2) return -sine[k-Nmax4];// N/4<k<N/2
  60. if(k <= Nmax3_4) return -sine[k-Nmax2];// N/2<k<(3/4)N
  61. return sine[k-Nmax3_4]; // (3/4)N<k<N
  62. }
  63. fftType fftSin_n(long k){ return sine[k]; } // k < Nmax4
  64. fftType fftCos_n(long k){ return sine[Nmax4-k]; }
  65. /***************************************
  66. It makes the largest sine table first.
  67. Set "maxsizebit" a FFT_MAX_SIZE_BITS.
  68. maxsizebit = 0 : free memory
  69. maxsizebit : same value previous one, do nothing
  70. ****************************************/
  71. int MakeSinTable(int maxsizebit){
  72. if(!maxsizebit){ //free memory
  73. if(tableSize){ delete[] sine; sine = NULL; tableSize = 0; }
  74. return -1;
  75. } else if(L == maxsizebit) return 1; // same table
  76. SetNSize(maxsizebit);
  77. long p;
  78. delete[] sine;
  79. delete[] cosine;
  80. if( (sine = new fftType[tableSize]) == NULL) return 1;
  81. # if 0
  82. long q,r;
  83. if( (cosine = new fftType[tableSize]) == NULL ) return 1;
  84. // cr[] and sr[] : table of cos(2*pi/(2^r)) and sin(2*pi/(2^r)) r = 0,...,L
  85. // Almost no this part uses time.
  86. fftType cr[L+1], sr[L+1];
  87. cr[0] = 1.0; cr[1] = -1.0; cr[2] = 0.0;
  88. sr[0] = sr[1] = 0.0; sr[2] = 1.0;
  89. fftType pi = M_PI, x;
  90. long m = 4;
  91. for(r = 3; r < L; r++){
  92. x= pi/m;
  93. cr[r] = fftCos(x);
  94. sr[r] = fftSin(x);
  95. m *= 2;
  96. }
  97. /***************
  98. table of sine[n] = sin(2*pi*n/N) and cosine[n] = cos(2*pi*n/N)
  99. (0 < n < N/4) by an addtion theorem
  100. Let n = 2^r + q = p + q , p = 2^r
  101. sine[p+q]
  102. = sin(2*pi*(p+q)/N)= sin(2*pi*p/N)cos(2*pi*q/N)+cos(2*pi*p/N)sin(2*pi*q/N)
  103. = sin(2*pi/2^(L-r))*cos(2*pi*q/N) + cos(2*pi/2^(L-r))sin(2*pi*q/N)
  104. = sr[L-r]*cosine[q]+cr[L-r]*sine[q]
  105. sine[p]=sin(2*pi*2^r/2^L) = sin(2*pi/2^(L-r)) = sr[L-r]
  106. then
  107. sine[p+q] = sine[p]*cosine[q]+cos[p]*sine[q]
  108. same way
  109. cosine[p+q] = cosine[p]*cosine[q]-sine[p]*sine[q];
  110. ****************/
  111. Timer timer(true);
  112. r = 0; sine[0] = 0.0; sine[n4] = 1.0; cosine[0]=1.0; cosine[n4]=0.0;
  113. for(p = 1; p < n4 ; p *= 2){
  114. sine[p] = sr[L -r]; cosine[p] = cr[L -r]; r++;
  115. for(q = 0; q < p ; q++){
  116. sine[p+q] = sine[p]*cosine[q]+cosine[p]*sine[q];
  117. cosine[p+q] = cosine[p]*cosine[q]-sine[p]*sine[q];
  118. }
  119. // here p+q<= N/4
  120. }
  121. delete[] cosine; cosine = NULL; // cosine is not necesary
  122. double t = timer.Stop();
  123. cout << "in MakeSinTable() t = " << t << endl;
  124. #else
  125. // sine[n] = sin(2*pi*n/N)
  126. Timer timer(true);
  127. fftType x, pi2N = M_PI;
  128. pi2N *= 2; // 2*pi
  129. pi2N /= Nmax; // 2*pi/N
  130. sine[0] = 0.0; sine[Nmax4] = 1.0;
  131. for(p = 1; p < Nmax4 ; p++){
  132. x = p*pi2N;
  133. sine[p] = fftSin(x);
  134. }
  135. double t = timer.Stop();
  136. cout << "in MakeSinTable() t = " << t << endl;
  137. return 0; // OK
  138. }
  139. #endif
  140. /*----------------------- end of sine table---------------------------*/

sinFFTtb.cpp : last modifiled at 2017/08/29 15:42:20(4,918 bytes)
created at 2017/10/03 15:04:05
The creation time of this html file is 2017/10/07 10:54:16 (Sat Oct 07 10:54:16 2017).